﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XTYAPI.通讯
{
    public static  class BitConvertHelper
    {
        public enum DataMode
        {
            /// <summary>
            /// 大端字节 如西门子PLC 去优化块的访问
            /// </summary>
            ABCD,
            /// <summary>
            /// 小端字节 如C#  x86架构的PC
            /// </summary>
            DCBA,
            /// <summary>
            /// 小端字 如信捷 
            /// </summary>
            CDAB
        }
        /// <summary>
        /// 大小端转换带数据截取
        /// </summary>
        /// <param name="value">原数组</param>
        /// <param name="startIndex">要截取的起始索引</param>
        /// <param name="count">截取字节数</param>
        /// <param name="dataMode">大小端模式</param>
        /// <returns></returns>
        private static byte[] ToBigLittle(byte[] value, int startIndex, int count, DataMode dataMode)
        {
            byte[] result = new byte[count];
            switch (dataMode)
            {
                case DataMode.ABCD:
                    for (int i = 0; i < count; i++)
                    {
                        result[i] = value[startIndex + count - 1 - i];
                    }
                    break;
                case DataMode.DCBA:
                    for (int i = 0; i < count; i++)
                    {
                        result[i] = value[startIndex + i];
                    }
                    break;
                case DataMode.CDAB:
                    for (int i = 0; i < count/2; i++)
                    {
                        result[i * 2 + 0] = value[startIndex + i * 2 + 1];
                        result[i * 2 + 1] = value[startIndex + i * 2 + 0];
                    }
                    break;
                default:
                    break;
            }
            return result;
        }
        /// <summary>
        /// 大小端转换 不带数据截取
        /// </summary>
        /// <param name="value">数组</param>
        /// <param name="big">是否大端</param>
        /// <returns></returns>
        private static byte[] ToBigLittle(byte[] value, DataMode dataMode=DataMode.CDAB)
        {  
            byte[] result = ToBigLittle(value, 0, value.Length, dataMode);
            return result;
        }
        /// <summary>
        /// 将通信得到的数组转为short16位
        /// </summary>
        /// <param name="source">原数组</param>
        /// <param name="index">起始位置</param>
        /// <param name="big">大小端</param>
        /// <returns></returns>
        public static short ToShort(byte[] source,int index, DataMode dataMode = DataMode.CDAB)
        {
            byte[] bs = ToBigLittle(source, index, 2, dataMode);
            return BitConverter.ToInt16(bs,0);
        }
        /// <summary>
        /// 将通信得到的数组转为Float浮点位
        /// </summary>
        /// <param name="source"></param>
        /// <param name="index"></param>
        /// <param name="big"></param>
        /// <returns></returns>
        public static float ToFloat(byte[] source, int index, DataMode dataMode = DataMode.CDAB)
        {
            byte[] bs = ToBigLittle(source, index, 4, dataMode);
            return BitConverter.ToSingle(bs, 0);
        }
        /// <summary>
        /// 获取short对应的数组 顺便填充到数组的指定位置
        /// </summary>
        /// <param name="value"></param>
        /// <param name="source"></param>
        /// <param name="index"></param>
        /// <param name="big"></param>
        public static void GetBytes(short value,byte[] source,int index, DataMode dataMode = DataMode.CDAB)
        {
            byte[] bs = ToBigLittle(BitConverter.GetBytes(value), dataMode);
            for (int i = 0; i < bs.Length; i++)
            {
                source[index + i] = bs[i];
            }
        }
        /// <summary>
        /// 获取short对应的数组 顺便填充到数组的指定位置
        /// </summary>
        /// <param name="value"></param>
        /// <param name="source"></param>
        /// <param name="index"></param>
        /// <param name="big"></param>
        public static void GetBytes(float value, byte[] source, int index, DataMode dataMode = DataMode.CDAB)
        {
            byte[] bs = ToBigLittle(BitConverter.GetBytes(value), dataMode);
            for (int i = 0; i < bs.Length; i++)
            {
                source[index + i] = bs[i];
            }
        }
    }
}
